//
//  ProblemOffer04.swift
//  TestProject
//
//  Created by 武侠 on 2021/7/21.
//  Copyright © 2021 zhulong. All rights reserved.
//

import UIKit

/*
 剑指 Offer 04. 二维数组中的查找 ✅
 在一个 n * m 的二维数组中，每一行都按照从左到右递增的顺序排序，每一列都按照从上到下递增的顺序排序。请完成一个高效的函数，输入这样的一个二维数组和一个整数，判断数组中是否含有该整数。

 示例:
 现有矩阵 matrix 如下：
 [
   [1,   4,  7, 11, 15],
   [2,   5,  8, 12, 19],
   [3,   6,  9, 16, 22],
   [10, 13, 14, 17, 24],
   [18, 21, 23, 26, 30]
 ]
 给定 target = 5，返回 true。
 给定 target = 20，返回 false。
 限制：
 0 <= n <= 1000
 0 <= m <= 1000
 */
@objcMembers class ProblemOffer04: NSObject {
    func solution() {
        print(findNumberIn2DArray([
            [1,   4,  7, 11, 15],
            [2,   5,  8, 12, 19],
            [3,   6,  9, 16, 22],
            [10, 13, 14, 17, 24],
            [18, 21, 23, 26, 30]
          ], 5))
        
        print(findNumberIn2DArray([
            [1,   4,  7, 11, 15],
            [2,   5,  8, 12, 19],
            [3,   6,  9, 16, 22],
            [10, 13, 14, 17, 24],
            [18, 21, 23, 26, 30]
          ], 20))
    }
    
    /*
     1: 从右上角开始，v = [i][j] i = 0, j = matrix[0].count
     2: 如果：v > target，那么整列都不符合，那么让 j--
     3: 如果：v < target, 说明[i][0～j]都不符合，那么让i--
     4: 直到找到v=target，或者发生越界 i<0||j<0||j>=matrix[0].count||i>=matrix.count
     */
    func findNumberIn2DArray(_ matrix: [[Int]], _ target: Int) -> Bool {
        if matrix.count == 0 || matrix[0].count == 0 || matrix[0][0] > target || matrix.last!.last! < target {
            return false
        }
        var i = 0, j = matrix[0].count-1
        while i >= 0, j >= 0, i < matrix.count, j < matrix[0].count {
            if matrix[i][j] == target {
                return true
            } else if matrix[i][j] > target {       // 说明[i~len][j]都 > target
                j -= 1
            } else {                                // 说明[i][0~j]都 < target
                i += 1
            }
        }
        
        return false
    }
}
